// @(#)ctrl.cc
// Time-stamp: <2009-01-08 17:29:56 root>
// Copyright 2008 Julian Qian
// Author: lancer@pdn
// Version: $Id: ctrl.cc,v 0.0 2008/12/30 03:51:43 lancer Exp $
// Keywords: 

#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>


#include "ctrl.hh"
#include "excep.hh"
#include "alarm.hh"
#include "log.hh"
#include "heart.hh"


Ctrl::Ctrl(){
    
}

Ctrl::~Ctrl(){
    
}

void
Ctrl::msg_servo(){
    int msgid;
    CTRL_MSG mala;

    try{
        _ala = Alarm::theAlarm();
    }
    catch(...){
        throw MsgServoException("Alarm");
    }
    try{
        _ht = Heart::theHeart();
    }
    catch(...){
        throw MsgServoException("Heart");
    }
    
    if(-1 == (msgid = msgget((key_t)MSG_KEY, 0666 | IPC_CREAT)) ){
        throw MsgServoException("msgget");
    }

    ALARM_PAIR ap;
    // receive
    while(1){
        if(-1 == msgrcv(msgid, (void*)&mala, sizeof(mala.data), 0,0)){
            throw MsgServoException(strerror(errno));
        }

        switch(mala.msg_type){
        case MSG_TYPE_ALARM:
            if(parse_msg_alarm(mala.data, &ap)){
                LDebug("push_alarm => " << ap.devid << ", alarm " << ap.alarm);
                _ala->queue_ctrl(ap.devid, ap.alarm);
            }
            break;
        case MSG_TYPE_MSG:
            break;
        case MSG_TYPE_CHECK:
            if(NULL == _ht->get_proto(atoi(mala.data))){
                // TODO:
            }
        }
    }    
}

bool
Ctrl::parse_msg_alarm(char* buf, ALARM_PAIR* ap){
    char *first, *second;
    // buf: devid,alarm --> "123,bf"
    first = strtok(buf, ",");
    second = strtok(NULL, ",");

    LDebug("parse msg:" << first <<"=>" << second);
    
    if(NULL == second){
        return false;
    }

    devid_t devid;
    alarm_t alarm;

    if((ap->devid = (devid_t)atoi(first)) <= 0){
        LDebug("alarm devid: " << ap->devid);
        return false;
    }

    ap->alarm = _ala->alarm_ctl(second);
    
    return true;
}

void
Ctrl::push_alarm(char* msg){
    CTRL_MSG mala;
    int msgid;
    
    if( -1 == (msgid = msgget((key_t)MSG_KEY, 0666 | IPC_CREAT))){
        throw MsgPushException("msgget");
    }

    mala.msg_type = MSG_TYPE_ALARM;
    strncpy(mala.data, msg, MSG_LEN);
    
    if(-1 == msgsnd(msgid, (void *)&mala, sizeof(mala.data), 0)){
        throw MsgPushException(strerror(errno));
    }
}

void
Ctrl::check_devid(char* devid){
    CTRL_MSG mala;
    int msgid;
    
    if( -1 == (msgid = msgget((key_t)MSG_KEY, 0666 | IPC_CREAT))){
        throw MsgPushException("msgget");
    }

    mala.msg_type = MSG_TYPE_CHECK;
    strncpy(mala.data, devid, MSG_LEN);
    
    if(-1 == msgsnd(msgid, (void *)&mala, sizeof(mala.data), 0)){
        throw MsgPushException(strerror(errno));
    }
}
